
\chapter{Libraries}

\label{appendix:libraries}

This appendix describes various software packages which are not
officially part of the {\bf T} language but which are of general utility.
Some are available within the implementations
directly, while others must be loaded from external files
using {\tt LOAD}.



\section{Tables}

\label{tables}

{\bf T3.1} contains generalized hash tables.  A table associates
a {\it key} with a {\it value}.  {\mbox {\tt MAKE-HASH-TABLE}}
is the most general way to make a hash table.  In addition, 
the most common types of tables have been predefined.
\begin{inset}{Caution:}
This feature is experimental and may go away or change in future
releases.
\end{inset}

Tables should be used in place of property lists.

\index{MAKE-HASH-TABLE@{\tt MAKE-HASH-TABLE}}
{\mbox {\tt (MAKE-HASH-TABLE {\it type? hash comparator gc? id}) $\longrightarrow$\  {\it table}}}
\hfill  

\begin{inset}{}
{\mbox {\tt MAKE-HASH-TABLE}} creates a table which associates keys to values.
Any object may be a key or a value.

\begin{description}

\item[{{\it type?}}] --- is a predicate.  All keys in the table must
answer true to the predicate {\it type?}.

\item[{{\it hash}}] --- is a procedure from keys to fixnums which
is used to hash the table entries.

\item[{{\it comparator}}] --- is an equality predicate on keys.

\item[{{\it gc?}}] --- is a boolean value which specifies whether the
hash procedure is dependent on the memory location(s) occupied
by the object, i.e.  whether or not the table must be rehashed
after a garbage collection.

\item[{{\it id}}] --- is an identifier used by the print method of the table.
\end{description}
\end{inset}

\index{HASH-TABLE?@{\tt HASH-TABLE?}}
{\mbox {\tt (HASH-TABLE? {\it object}) $\longrightarrow$\  {\it boolean}}}
\hfill  

\begin{inset}{}
{\mbox {\tt HASH-TABLE?}} returns true if the {\it object} is a hash table.
\end{inset}

\index{TABLE-ENTRY@{\tt TABLE-ENTRY}}
{\mbox {\tt (TABLE-ENTRY {\it table key}) $\longrightarrow$\  {\it object}}}
\hfill Settable

\begin{inset}{}
{\mbox {\tt TABLE-ENTRY}} returns the {\it object} associated with the
{\it key} in the {\it table} if there is an entry for {\it key},
otherwise returns {\it false}.
\end{inset}

\index{WALK-TABLE@{\tt WALK-TABLE}}
{\mbox {\tt (WALK-TABLE {\it proc table}) $\longrightarrow$\  {\it undefined}}}
\hfill  

\begin{inset}{}
{\mbox {\tt WALK-TABLE}} invokes {\it proc}, a procedure of two arguments,
on each {\it keyvalue} association in the {\it table}.
Note that it is an error to perform any operations on the table 
while walking it.
\end{inset}

The following common table types have been predefined as follows:

\index{MAKE-TABLE@{\tt MAKE-TABLE}}
{\mbox {\tt (MAKE-TABLE {\it . id}) $\longrightarrow$\  {\it table}}}
\hfill  

\begin{inset}{}
{\mbox {\tt MAKE-TABLE}} creates a {\it table} in which any object
can be a {\it key} and {\mbox {\tt EQV?}} is used as the equality
predicate on {\it keys}.
\end{inset}

\index{TABLE?@{\tt TABLE?}}
{\mbox {\tt (TABLE? {\it object}) $\longrightarrow$\  {\it boolean}}}
\hfill  

\begin{inset}{}
{\mbox {\tt TABLE?}} returns true if the {\it object} is an {\mbox {\tt EQ?}} table.
\end{inset}

\index{MAKE-STRING-TABLE@{\tt MAKE-STRING-TABLE}}
{\mbox {\tt (MAKE-STRING-TABLE {\it .  id}) $\longrightarrow$\  {\it table}}}
\hfill  

\begin{inset}{}
{\mbox {\tt MAKE-STRING-TABLE}} creates a {\it table} in which
the {\it keys} must be {\it strings} and
{\mbox {\tt STRING-EQUAL?}} is used as the equality predicate on
{\it keys}.
\end{inset}

\index{STRING-TABLE?@{\tt STRING-TABLE?}}
{\mbox {\tt (STRING-TABLE? {\it object}) $\longrightarrow$\  {\it boolean}}}
\hfill  

\begin{inset}{}
{\mbox {\tt STRING-TABLE?}} returns true if the {\it object} is a
{\it string-table}.
\end{inset}

\index{MAKE-SYMBOL-TABLE@{\tt MAKE-SYMBOL-TABLE}}
{\mbox {\tt (MAKE-SYMBOL-TABLE {\it . id}) $\longrightarrow$\  {\it symbol-table}}}
\hfill  

\begin{inset}{}
{\mbox {\tt MAKE-SYMBOL-TABLE}} creates a table in which the keys
must be {\it symbols} and {\mbox {\tt EQ?}} is used as the equality
predicate on keys.
\end{inset}

\index{SYMBOL-TABLE?@{\tt SYMBOL-TABLE?}}
{\mbox {\tt (SYMBOL-TABLE? {\it object}) $\longrightarrow$\  {\it boolean}}}
\hfill  

\begin{inset}{}
{\mbox {\tt SYMBOL-TABLE?}} returns true if the {\it object} is a
{\it symbol-table}.
\end{inset}

\section{Random Integers}


\index{MAKE-RANDOM@{\tt MAKE-RANDOM}}
{\mbox {\tt (MAKE-RANDOM {\it seed}) $\longrightarrow$\  {\it thunk}}}
\hfill  

\begin{inset}{}
{\mbox {\tt MAKE-RANDOM}} takes a {\it seed} which is a fixnum
and returns a {\it thunk}.  The thunk returns a new
pseudo-random {\it integer}, {\it x\/}, in the range 
\begin{codexenv}
{\mbox {\tt MOST-NEGATIVE-FIXNUM}} $\leq$ {\it x\/} $\leq$ {\mbox {\tt MOST-POSITIVE-FIXNUM}}
\end{codexenv}
each time it is invoked.
\end{inset}

\section{List utilities}



\index{MEM@{\tt MEM}}
{\mbox {\tt (MEM {\it predicate object list\/}) $\longrightarrow$\  {\it list\/}}}
\hfill  

\begin{inset}{}
Returns the first {\it tail\/} of {\it list\/} such that
{\tt ({\it predicate object\/} (CAR {\it tail\/}))}.
\begin{codexenv}
(MEM EQ? 'A '(B A D E))  $\Longrightarrow$\   (A D E)
\end{codexenv}
\end{inset} 

\index{MEMQ@{\tt MEMQ}}
{\mbox {\tt (MEMQ {\it object list\/}) $\longrightarrow$\  {\it list\/}}}
\hfill  

\begin{inset}{}
\begin{codexenv}
(MEMQ {\it object list\/})  $\equiv$  (MEM EQ? {\it object list\/})
\end{codexenv}
\end{inset} 


\index{ANY@{\tt ANY}}
{\mbox {\tt (ANY {\it predicate . lists\/}) $\longrightarrow$\  {\it object\/}}}
\hfill  

\begin{inset}{}
Calls the {\it predicate\/} on successive elements of the {\it lists\/},
stopping as soon as the {\it predicate\/} returns a value other than false.
This value is returned as {\tt ANY}'s value.
\begin{codexenv}
    \begin{tabular}{lll}
(ANY NUMBER? '(A B 3 FOO))  &$\Longrightarrow$\ &  {\it true} \\
(ANY NUMBER? '(A B C FOO))  &$\Longrightarrow$\ &  {\it false} \\
(ANY {\tt $<$} '(1 2 3) '(6 6 6))   &$\Longrightarrow$\ &  {\it true} \\
(ANY MEMQ '(A B C) '((X B) (U B Z) (C D E F)))  &$\Longrightarrow$\ &  (B Z)
\end{tabular}
    \end{codexenv}
\end{inset} 

\index{ANYCDR@{\tt ANYCDR}}
{\mbox {\tt (ANYCDR {\it predicate . lists\/}) $\longrightarrow$\  {\it object\/}}}
\hfill  

\begin{inset}{}
Like {\tt ANY}, but the {\it predicate\/} is called on successive
tails of the {\it lists\/} instead of successive elements.
\end{inset} 

\index{EVERY@{\tt EVERY}}
{\mbox {\tt (EVERY {\it predicate . lists\/}) $\longrightarrow$\  {\it object\/}}}
\hfill  

\begin{inset}{}
Calls the {\it predicate\/} on successive elements of the {\it lists\/},
stopping as soon as the {\it predicate\/} returns false.
If for every element {\it predicate\/} returns true, {\tt EVERY}
returns the value of the last call.
\begin{codexenv}
(EVERY NUMBER? '(1 2 3 -15.7))  $\Longrightarrow$\   {\it true} \\
(EVERY NUMBER? '(1 2 3 FOO))	$\Longrightarrow$\   {\it false} \\
(EVERY ASSQ '(A B C) \\
     '(((A X) (X Y)) ((A J) (B K)) ((C D) (T U)))) \\
  $\Longrightarrow$\   (C D)
\end{codexenv}
\end{inset} 

\index{EVERYCDR@{\tt EVERYCDR}}
{\mbox {\tt (EVERYCDR {\it predicate . lists\/}) $\longrightarrow$\  {\it object\/}}}
\hfill  

\begin{inset}{}
Like {\tt EVERY}, but the {\it predicate\/} is called on successive
tails of the {\it lists\/} instead of successive elements.
\end{inset} 

\index{EVERYCDR?@{\tt EVERYCDR?}}
{\mbox {\tt (EVERYCDR? {\it predicate . lists\/}) $\longrightarrow$\  {\it boolean\/}}}
\hfill  

\begin{inset}{}
\begin{codexenv}
(EVERYCDR? {\it predicate . lists\/})  $\equiv$  (TRUE? (EVERYCDR {\it predicate . lists\/}))
\end{codexenv}
\end{inset} 

\index{ANYCDR?@{\tt ANYCDR?}}
{\mbox {\tt (ANYCDR? {\it predicate . lists\/}) $\longrightarrow$\  {\it boolean\/}}}
\hfill  

\begin{inset}{}
\begin{codexenv}
(ANYCDR? {\it predicate . lists\/})  $\equiv$  (TRUE? (ANYCDR {\it predicate . lists\/}))
\end{codexenv}
\end{inset} 

\index{POS@{\tt POS}}
{\mbox {\tt (POS {\it predicate object list\/}) $\longrightarrow$\  {\it integer\/} {\rm or} {\it false\/}}}
\hfill  

\begin{inset}{}
Returns the position of the first item in {\it list\/} such that
{\tt ({\it predicate object item\/})}, or false if there is no such
item.
\end{inset} 

\index{POSQ@{\tt POSQ}}
{\mbox {\tt (POSQ {\it object list\/}) $\longrightarrow$\  {\it integer\/} {\rm or} {\it false\/}}}
\hfill  

\begin{inset}{}
\begin{codexenv}
(POSQ {\it object list\/})  $\equiv$  (POS EQ? {\it object list\/})
\end{codexenv}
\end{inset} 

\index{APPEND-REVERSE@{\tt APPEND-REVERSE}}
{\mbox {\tt (APPEND-REVERSE {\it list ending\/}) $\longrightarrow$\  {\it list\/}}}
\hfill  

\begin{inset}{}
{\tt \begin{tabbing}
(APPEND-REVERSE \= {\it list ending\/})  $\equiv$ \\
  \> (APPEND (REVERSE {\it list\/}) {\it ending\/}) \\

(APPEND-REVERSE '(A B C) '(D E))  $\Longrightarrow$\   (C B A D E)
\end{tabbing}}
\end{inset} 

\index{APPEND-REVERSE!@{\tt APPEND-REVERSE!}}
{\mbox {\tt (APPEND-REVERSE! {\it list ending\/}) $\longrightarrow$\  {\it list\/}}}
\hfill  

\begin{inset}{}
\begin{codexenv}
(APPEND-REVERSE! {\it list ending\/})  $\equiv$ \\
(APPEND! (REVERSE! {\it list\/}) {\it ending\/})
\end{codexenv}
\end{inset} 

\section{Type-specific arithmetic}


A \iix{fixnum} is an integer whose magnitude lies within an
implementation-dependent range.  This range is guaranteed to  all
integers which are acceptable as array, string, or vector indices.
{\bf T} guarantees that fixnums will have at least 24 bits.
In {\bf T3.1}, this range is the half-open interval
\begin{codexenv}
[2$^{\hbox{-29}}$,2$^{\hbox{29}}$). \\
\end{codexenv}

\index{FIXNUM?@{\tt FIXNUM?}}
{\mbox {\tt (FIXNUM? {\it object\/}) $\longrightarrow$\  {\it boolean\/}}}
\hfill Type predicate

\label{FIXNUM?}
\begin{inset}{}
Returns true if {\it object\/} is a fixnum.
\end{inset} 

\index{MOST-POSITIVE-FIXNUM@{\tt MOST-POSITIVE-FIXNUM}}
{\mbox {\tt MOST-POSITIVE-FIXNUM $\longrightarrow$\  {\it integer\/}}}
\hfill  

\begin{inset}{}
Returns the largest integer value within the fixnum range.  No integer
answering true to {\tt FIXNUM?} is greater than {\tt MOST-POSITIVE-FIXNUM}.
\end{inset}

\index{MOST-NEGATIVE-FIXNUM@{\tt MOST-NEGATIVE-FIXNUM}}
{\mbox {\tt MOST-NEGATIVE-FIXNUM $\longrightarrow$\  {\it integer\/}}}
\hfill  

\begin{inset}{}
Returns the smallest integer value within the fixnum range.  No integer
answering true to {\tt FIXNUM?} is less than {\tt MOST-NEGATIVE-FIXNUM}.
{\tt \begin{tabbing}
(FIXNUM? \= {\it x\/}) \\
\> $\equiv$\\
(AND \= (INTEGER? X) \+ \\
     ($>$= {\it x\/} MOST-NEGATIVE-FIXNUM) \\
     ($<$= {\it x\/} MOST-POSITIVE-FIXNUM))
\end{tabbing}}
\end{inset}

The following procedures are defined for performing type-restricted
arithmetic.  These procedures should be considered specializations of
their corresponding generic arithmetic procedures.  They assume
restrictions on the types of their arguments and results.  The prefix
{\tt FX} means ``fixnum-specific'' and {\tt FL} means
``flonum-specific.''  For example,
\begin{codexenv}
(FX+ {\it x\/} {\it y\/})   \\
$\equiv$  (ENFORCE FIXNUM? (+ (ENFORCE FIXNUM? {\it x\/}) (ENFORCE FIXNUM? {\it y\/})))
\end{codexenv}
{\bf T} will implement calls to these type-specific procedures in a more
efficient manner than calls to the corresponding generic procedures.

The following list catalogs the available routines.  In most case the
effect of the procedure should be analogous to the example above.  The
one exception is {\tt FX/}, which is a specialization of the truncated
(integer) division routine {\tt QUOTIENT}, not of the division routine {\tt /}.
\begin{codexenv}
    \begin{tabular}{lll}
(FX+ {\it fixnum1 fixnum2\/}) &$\longrightarrow$\ & {\it fixnum\/}\index{FX+@{\tt FX+}} \\
(FL+ {\it fixnum1 fixnum2\/}) &$\longrightarrow$\ & {\it flonum\/}\index{FL+@{\tt FL+}} \\
(FX- {\it fixnum1 fixnum2\/}) &$\longrightarrow$\ & {\it fixnum\/}\index{FX-@{\tt FX-}} \\
(FL- {\it flonum1 flonum2\/}) &$\longrightarrow$\ & {\it flonum\/}\index{FL-@{\tt FL-}} \\
(FX* {\it fixnum1 fixnum2\/}) &$\longrightarrow$\ & {\it fixnum\/}\index{FX*@{\tt FX*}} \\
(FL* {\it fixnum1 fixnum2\/}) &$\longrightarrow$\ & {\it flonum\/}\index{FL*@{\tt FL*}} \\
(FX/ {\it fixnum1 fixnum2\/}) &$\longrightarrow$\ & {\it fixnum\/}\index{FX/@{\tt FX/}} \\
(FL/ {\it flonum1 flonum2\/}) &$\longrightarrow$\ & {\it flonum\/}\index{FL/@{\tt FL/}} \\
(FX= {\it fixnum1 fixnum2\/}) &$\longrightarrow$\ & {\it boolean\/}\index{FX=@{\tt FX=}} \\
(FL= {\it flonum1 flonum2\/}) &$\longrightarrow$\ & {\it boolean\/}\index{FL=@{\tt FL=}} \\
(FX$<$ {\it fixnum1 fixnum2\/}) &$\longrightarrow$\ & {\it boolean\/}\index{FX$<$@{\tt FX$<$}} \\
(FL$<$ {\it flonum1 flonum2\/}) &$\longrightarrow$\ & {\it boolean\/}\index{FL$<$@{\tt FL$<$}} \\
(FX$>$ {\it fixnum1 fixnum2\/}) &$\longrightarrow$\ & {\it boolean\/}\index{FX>@{\tt FX>}} \\
(FL$>$ {\it flonum1 flonum2\/}) &$\longrightarrow$\ & {\it boolean\/}\index{FL>@{\tt FL>}} \\
(FXN= {\it fixnum1 fixnum2\/}) &$\longrightarrow$\ & {\it boolean\/}\index{FXN=@{\tt FXN=}} \\
(FLN= {\it flonum1 flonum2\/}) &$\longrightarrow$\ & {\it boolean\/}\index{FLN=@{\tt FLN=}} \\
(FX$>$= {\it fixnum1 fixnum2\/}) &$\longrightarrow$\ & {\it boolean\/}\index{FX>=@{\tt FX>=}} \\
(FL$>$= {\it flonum1 flonum2\/}) &$\longrightarrow$\ & {\it boolean\/}\index{FL>=@{\tt FL>=}} \\
(FX$<$= {\it fixnum1 fixnum2\/}) &$\longrightarrow$\ & {\it boolean\/}\index{FX$<$=@{\tt FX$<$=}} \\
(FL$<$= {\it flonum1 flonum2\/}) &$\longrightarrow$\ & {\it boolean\/}\index{FL$<$=@{\tt FL$<$=}} \\
(FIXNUM-REMAINDER {\it fixnum1 fixnum2\/}) &$\longrightarrow$\ & {\it fixnum\/}\index{FIXNUM-REMAINDER@{\tt FIXNUM-REMAINDER}} \\
(FX-REM {\it fixnum1 fixnum2\/}) &$\longrightarrow$\ & {\it fixnum\/}\index{FX-REM@{\tt FX-REM}} {\bf T3}: $\equiv$ FIXNUM-REMAINDER \\
(FIXNUM-ODD? {\it fixnum\/}) &$\longrightarrow$\ & {\it boolean\/}\index{FIXNUM-ODD?@{\tt FIXNUM-ODD?}} \\
(FIXNUM-EVEN? {\it fixnum\/}) &$\longrightarrow$\ & {\it boolean\/}\index{FIXNUM-EVEN?@{\tt FIXNUM-EVEN?}} \\
(FIXNUM-ABS {\it fixnum\/}) &$\longrightarrow$\ & {\it fixnum\/}\index{FIXNUM-ABS@{\tt FIXNUM-ABS}} \\
(FIXNUM-MIN {\it fixnum1 fixnum2\/}) &$\longrightarrow$\ & {\it fixnum\/}\index{FIXNUM-MIN@{\tt FIXNUM-MIN}} \\
(FIXNUM-MAX {\it fixnum1 fixnum2\/}) &$\longrightarrow$\ & {\it fixnum\/}\index{FIXNUM-MAX@{\tt FIXNUM-MAX}} \\
(FIXNUM-LOGAND {\it fixnum1 fixnum2\/}) &$\longrightarrow$\ & {\it fixnum\/}\index{FIXNUM-LOGAND@{\tt FIXNUM-LOGAND}} \\
(FIXNUM-LOGIOR {\it fixnum1 fixnum2\/}) &$\longrightarrow$\ & {\it fixnum\/}\index{FIXNUM-LOGIOR@{\tt FIXNUM-LOGIOR}} \\
(FIXNUM-LOGNOT {\it fixnum\/}) &$\longrightarrow$\ & {\it fixnum\/}\index{FIXNUM-LOGNOT@{\tt FIXNUM-LOGNOT}} \\
(FIXNUM-ASHR {\it fixnum\/}) &$\longrightarrow$\ & {\it fixnum\/}\index{FIXNUM-ASHR@{\tt FIXNUM-ASHR}} \\
(FIXNUM-ASHL {\it fixnum\/}) &$\longrightarrow$\ & {\it fixnum\/}\index{FIXNUM-ASHL@{\tt FIXNUM-ASHL}} \\
(FIXNUM-$>$FLONUM {\it fixnum\/}) &$\longrightarrow$\ & {\it flonum\/}\index{FIXNUM->FLONUM@{\tt FIXNUM->FLONUM}} \\
(FLONUM-$>$FIXNUM {\it flonum\/}) &$\longrightarrow$\ & {\it fixnum\/}\index{FLONUM->FIXNUM@{\tt FLONUM->FIXNUM}}
\end{tabular}
    \end{codexenv}
